home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Environments / SmallEiffel 0.3.3 / SmallEiffel 68k / lib_std / general.e < prev    next >
Encoding:
Text File  |  1996-06-13  |  16.1 KB  |  641 lines  |  [TEXT/EDIT]

  1. -- Part of SmallEiffel -- Read DISCLAIMER file -- Copyright (C) 
  2. -- Dominique COLNET and Suzanne COLLIN -- colnet@loria.fr
  3. --
  4. class GENERAL
  5. --        
  6. -- Platform-independent universal properties.
  7. -- This class is an ancestor to all developer-written classes.
  8. --
  9.  
  10. feature -- Access :
  11.    
  12.    generating_type: STRING is
  13.      -- Name of current object's generating type (type of 
  14.      -- which it is a direct instance).
  15.       external "CSE"
  16.       end;
  17.   
  18.    generator: STRING is
  19.      -- Name of current object's generating class (base class
  20.      -- of the type of witch it is a direct instance).
  21.       external "CSE"
  22.       end;
  23.    
  24.    id_object(id: INTEGER): ANY is
  25.      -- Object for wich `object_id' has returened `id'.
  26.      -- Void if none.
  27.       require
  28.      id /= 0;
  29.       do
  30.      c_inline_c("R=((T0 *)a1);");
  31.       end;
  32.    
  33.    object_id: INTEGER is
  34.      -- Value identifying current reference object.
  35.       require
  36.      not is_expanded_type
  37.       do
  38.      c_inline_c("R=((int)C);")
  39.       end;
  40.    
  41.    stripped(other: GENERAL): like other is
  42.      -- New created object with fields copied from current object, but
  43.      -- limited to attributes of type of `other'.
  44.       require
  45.      conformance: conforms_to(other);
  46.       do
  47.      not_yet_implemented;
  48.       ensure
  49.      stripped_to_other: Result.same_type(other);
  50.       end;
  51.    
  52. feature -- Status report :
  53.    
  54.    frozen conforms_to(other: GENERAL): BOOLEAN is
  55.      -- Does type of current object conform to type of other 
  56.      -- (as per Eiffel: The Language, chapter 13) ?
  57.       require
  58.      other_not_void: other /= Void;
  59.       do
  60.      not_yet_implemented;
  61.       end;
  62.    
  63.    frozen same_type(other: GENERAL): BOOLEAN is
  64.      -- Is type of current object identical to type of other.     
  65.       require
  66.      other_not_void: other /= Void;
  67.       do
  68.      if not is_expanded_type then
  69.         c_inline_c("R=((C->id)==(a1->id));");
  70.      end;
  71.       ensure
  72. --     definition: Result = (conforms_to(other) and
  73. --                   other.conforms_to(Current));
  74.       end;
  75.    
  76. feature -- Comparison :
  77.    
  78.    frozen deep_equal(some: GENERAL; other: like some): BOOLEAN is
  79.       do
  80.      if some = other then
  81.         Result := true;
  82.      elseif some = Void then
  83.      elseif other = Void then
  84.      elseif standard_equal(some,other) then
  85.         Result := true;
  86.      else
  87.         not_yet_implemented;
  88.      end;
  89.       ensure
  90.      shallow_implies_deep: standard_equal(some,other) 
  91.                    implies Result;
  92.      same_type: Result implies some.same_type(other);
  93.      symmetric: Result implies deep_equal(other,some);
  94.       end;
  95.    
  96.    frozen equal(some: ANY; other: like some): BOOLEAN is
  97.      -- Are `some' and `other' both Void or attached to
  98.      -- objects considered equal ?
  99.       do
  100.      if some = other then
  101.         Result := true;
  102.      elseif some = Void then
  103.      elseif other = Void then
  104.      else
  105.         Result := some.is_equal(other);
  106.      end;
  107.       ensure
  108.      definition: Result = (some = Void and other = Void) or else
  109.              ((some /= Void and other /= Void) and then
  110.               some.is_equal(other));
  111.       end;
  112.  
  113.    is_equal(other: like Current): BOOLEAN is
  114.      -- Is `other' attached to an object considered equal to 
  115.      -- current object ?
  116.       require
  117.      other_not_void: other /= Void
  118.       do
  119.      Result := standard_is_equal(other);
  120.       ensure
  121.      consistent: standard_is_equal(other) implies Result;
  122. -- ***     same_type: Result implies same_type(other);
  123. -- ELKS95 bug for expanded target.
  124.      symmetric: Result implies other.is_equal(Current);
  125.       end;
  126.    
  127.    frozen standard_equal(some: ANY; other: like some): BOOLEAN is
  128.      -- Are `some' and `other' both Void or attached to
  129.      -- field-by-field objects of the same type ?
  130.      -- Always use the default object comparison criterion.
  131.       do
  132.      if some = other then
  133.         Result := true;
  134.      elseif some = Void then
  135.      elseif other = Void then
  136.      elseif some.same_type(other) then
  137.         Result := some.standard_is_equal(other);
  138.      end;
  139.       ensure
  140.      definition: Result = (some = Void and other = Void) or else
  141.              ((some /= Void and other /= Void) and then
  142.               some.standard_is_equal(other));
  143.       end;
  144.  
  145.    frozen standard_is_equal(other: like Current): BOOLEAN is
  146.      -- Are Current and `other' field-by-field identical?
  147.       require
  148.      other /= Void
  149.       do
  150.      if is_expanded_type then
  151.         Result := other = Current;
  152.      elseif other = Current then
  153.         Result := true;
  154.      else
  155.         c_inline_c("R=!memcmp(C,a1,s[C->id]);");
  156.      end;
  157.       ensure
  158. -- ***     same_type: Result implies same_type(other);
  159. -- ELKS95 bug for expanded target.
  160.      symmetric: Result implies other.standard_is_equal(Current);
  161.       end;
  162.    
  163. feature -- Duplication :
  164.    
  165.    frozen clone(other: ANY): like other is
  166.      -- When argument `other' is Void, return Void
  167.      -- otherwise return `other.twin'.
  168.       do
  169.      if other /= Void then
  170.         Result := other.twin;
  171.      end;
  172.       ensure
  173.      equal: equal(Result,other);
  174.       end;
  175.  
  176.    frozen twin: like Current is
  177.      -- Return an initialized new object using target as model.
  178.      -- Result as the same `generating_type' as the target of the 
  179.      -- call. Before to be returned, the corresponding `copy' feature
  180.      -- is called.
  181.       do
  182.      if is_expanded_type then
  183.         if is_basic_expanded_type then
  184.            Result := Current;
  185.         else
  186.            Result := Current;
  187.            Result.copy(Current);
  188.         end;
  189.      else
  190.         c_inline_c("R=(T0 *)se_new(C->id);AF_1");
  191.         Result.copy(Current);
  192.         c_inline_c("AF_0");
  193.      end;
  194.       ensure
  195.      equal: Result.is_equal(Current);
  196.       end;
  197.  
  198.    copy(other: like Current) is
  199.      -- Update current object using fields of object attached
  200.      -- to `other', so as to yield equal objects.
  201.       require
  202.      other_not_void: other /= Void;
  203.      type_identity: same_type(other);
  204.       do
  205.      if is_expanded_type then
  206.         c_inline_c("C=a1;");
  207.      else
  208.         c_inline_c("memcpy(C,a1,s[C->id]);");
  209.      end;
  210.       ensure
  211.      is_equal: is_equal(other)
  212.       end;
  213.    
  214.    frozen deep_clone(other: GENERAL): like other is
  215.      -- Void if `other' is Void: otherwise, new object structure 
  216.      -- recursively duplicated from the one attached to other.
  217.       do
  218.      not_yet_implemented;
  219.       ensure
  220.      deep_equal: deep_equal(other,Result);
  221.       end;
  222.    
  223.    frozen standard_clone(other: ANY): like other is
  224.      -- Void if `other' is Void; otherwise new object 
  225.      -- field-by-field identical to `other'. 
  226.      -- Always use the default copying semantics.
  227.       do
  228.      if other /= Void then
  229.         c_inline_c("R=(T0 *)se_new(a1->id);%N%
  230.                %memcpy(R,a1,s[a1->id]);");
  231.      end;
  232.       ensure
  233.      equal: standard_equal(Result,other);
  234.       end;
  235.  
  236.     frozen standard_copy(other: like Current) is
  237.      -- Copy every field of `other' onto corresponding 
  238.      -- field of curent object.
  239.       require
  240.      other_not_void: other /= Void;
  241.      type_identity: same_type(other);
  242.       do
  243.      c_inline_c("memcpy(C,a1,s[a1->id]);");
  244.       ensure
  245.      is_standard_equal: standard_is_equal(other);
  246.       end;
  247.    
  248. feature -- Basic operations :
  249.    
  250.    frozen default: like Current is
  251.      -- Default value of current type.
  252.       do
  253.       end;
  254.    
  255.    frozen default_pointer: POINTER is
  256.      -- Default value of type POINTER (avoid the need to
  257.       -- write p.default for some `p' of type POINTER).
  258.       do
  259.       ensure
  260.      Result = Result.default;
  261.       end;
  262.    
  263.    default_rescue is
  264.      -- Handle exception if no Rescue clause (default do
  265.      -- nothing).
  266.       do
  267.       end;
  268.    
  269.    frozen do_nothing is
  270.      -- Execute a null action.
  271.       do
  272.       end;
  273.    
  274.    frozen Void: NONE is 
  275.       -- Void reference.
  276.       external "CSE" 
  277.       end;
  278.  
  279. feature -- Input and Output :
  280.    
  281.    frozen io: STD_INPUT_OUTPUT is
  282.      -- Handle to standard file setup.
  283.      -- To use the standard input/output file.
  284.       once
  285.      !!Result.make;
  286.       ensure
  287.      Result /= Void;
  288.       end; 
  289.    
  290.    frozen std_input: STD_INPUT is
  291.      -- To use the standard input file.
  292.       once
  293.      !!Result.make;
  294.       end; 
  295.    
  296.    frozen std_output: STD_OUTPUT is
  297.      -- To use the standard output file.
  298.       once
  299.      !!Result.make;
  300.       end; 
  301.    
  302.    frozen std_error: STD_ERROR is
  303.      -- To use the standard error file.
  304.       once
  305.      !!Result.make;
  306.       end; 
  307.    
  308. feature -- Object Printing :
  309.  
  310.    print(some: GENERAL) is
  311.      -- Write terse external representation of `some' on
  312.      -- `standard_output'.
  313.      -- This routine is automatically called to print the stack
  314.      -- when system `crash'. As user can redefine `print', 
  315.      -- `print_on' or `fill_tagged_out_memory', it is better to 
  316.      --  be sure not to have a second `crash'. 
  317.       do
  318.      if some = Void then
  319.         std_output.put_string("Void");
  320.      else
  321.         some.print_on(std_output);
  322.      end;
  323.       end;
  324.    
  325.    print_on(file: STD_FILE_WRITE) is
  326.      -- Default printing of current object.
  327.       do
  328.      tagged_out_memory.clear;
  329.      out_in_tagged_out_memory;
  330.      file.put_string(tagged_out_memory);
  331.       end;
  332.  
  333.    frozen tagged_out: STRING is
  334.      -- New string containing printable representation of current 
  335.      -- object, each field preceded by its attribute name, a 
  336.      -- colon and a space.
  337.       do
  338.      tagged_out_memory.clear;
  339.      fill_tagged_out_memory;
  340.      Result := tagged_out_memory.twin;
  341.       end;
  342.    
  343.    out: STRING is
  344.      -- Create a new string containing terse printable 
  345.      -- representation of current object;
  346.       do
  347.      tagged_out_memory.clear;
  348.      out_in_tagged_out_memory;
  349.      Result := tagged_out_memory.twin;
  350.       end;
  351.    
  352.    out_in_tagged_out_memory is
  353.       -- Append terse printable represention of current object
  354.       -- in `tagged_out_memory';
  355.       do
  356.      if is_basic_expanded_type then
  357.         fill_tagged_out_memory;
  358.      else
  359.         tagged_out_memory.append(generating_type);
  360.         if not is_expanded_type then
  361.            tagged_out_memory.extend('#');
  362.            object_id.append_in(tagged_out_memory);
  363.         end;
  364.         tagged_out_memory.extend('[');
  365.         fill_tagged_out_memory;
  366.         tagged_out_memory.extend(']');
  367.      end;
  368.       end;
  369.    
  370.    frozen tagged_out_memory: STRING is
  371.       once
  372.      !!Result.make(1024);
  373.       end;
  374.    
  375.    fill_tagged_out_memory is
  376.      -- Note : can be redefine to change printing of stack
  377.      --        when system crash.
  378.       do
  379.       end;
  380.    
  381. feature -- Named file handling :
  382.    
  383.    file_exists(path: STRING): BOOLEAN is
  384.       require
  385.      path /= Void;
  386.       local
  387.      p: POINTER;
  388.       do
  389.      p := path.to_external;
  390.      c_inline_c(
  391.          "{FILE *f=fopen(((char*)_p),%"r%");%N%
  392.      %R=(f != NULL);%N%
  393.      %if (R) fclose(f);}");
  394.       end;
  395.    
  396.    remove_file(path: STRING) is
  397.       require
  398.      path /= Void;
  399.       local
  400.      p: POINTER;
  401.       do
  402.      p := path.to_external;
  403.      c_inline_c("remove(((char*)_p));");
  404.       end;
  405.    
  406.    rename_file(old_path, new_path: STRING) is
  407.       require
  408.      old_path /= Void;
  409.      new_path /= Void;
  410.       local
  411.      op, np: POINTER;
  412.       do
  413.      op := old_path.to_external;
  414.      np := new_path.to_external;
  415.      c_inline_c("rename(((char*)_op),((char*)_np));");
  416.       end;
  417.  
  418. feature -- Access to command-line arguments :
  419.    
  420.    argument_count: INTEGER is
  421.      -- Number of arguments given to command that started
  422.      -- system execution (command name does not count).
  423.       do
  424.      Result := command_arguments.upper;
  425.       ensure
  426.      Result >= 0;
  427.       end;
  428.    
  429.    argument(i: INTEGER): STRING is
  430.      -- `i' th argument of command that started system execution 
  431.      -- Gives the command name if `i' is 0.
  432.       require
  433.      i >= 0;
  434.      i <= argument_count;
  435.       do
  436.      Result := command_arguments.item(i);
  437.       ensure
  438.      Result /= Void
  439.       end;
  440.  
  441.    frozen command_arguments: ARRAY[STRING] is
  442.      --                  ***** FIXED_ARRAY[STRING]
  443.      -- Give an acces to arguments command line including the
  444.      -- command name at index 0.
  445.       local
  446.      i: INTEGER;
  447.      arg: STRING;
  448.       once
  449.      from
  450.         c_inline_c("_i=se_argc-1;");
  451.         !!Result.make(0,i);
  452.      until
  453.         i < 0
  454.      loop
  455.         c_inline_c("_arg=((T0*)e2s(se_argv[_i]));");
  456.         Result.put(arg,i);
  457.         i := i - 1;
  458.      end;
  459.       ensure
  460.      Result.lower = 0; -- *****  FIXED_ARRAY 
  461.      not Result.empty
  462.       end;
  463.    
  464.    get_environment_variable(name: STRING): STRING is
  465.      -- To get the value of a system environment variable
  466.      -- (like "PATH" on Unix for example).
  467.      -- Gives Void when system variable `name' is undefined.
  468.       require
  469.      name /= Void
  470.       local
  471.      p: POINTER;
  472.       do
  473.      p := name.to_external;
  474.      c_inline_c("_p=((void*)getenv((char*)_p));");
  475.      if p.is_not_void then
  476.         c_inline_c("R=(T0*)e2s((char*)_p);");
  477.      end;
  478.       ensure
  479.      Result /= Void implies not Result.empty
  480.       end;
  481.    
  482. feature -- System calls and crashing :
  483.    
  484.    system(cmd: STRING) is
  485.      -- To execute a `cmd' at system level.
  486.      -- For example, "ls -l" on UNIX.
  487.       local
  488.      p: POINTER;
  489.       do
  490.      p := cmd.to_external;
  491.      c_inline_c("system(((char*)_p));");
  492.       end;
  493.    
  494.    frozen crash is
  495.      -- Print Run Time Stack (unless "-boost" mode) 
  496.      -- and then exit with `exit_failure_code'.
  497.      -- See also `print'.
  498.       do
  499.      c_inline_c("rsp();");
  500.      die_with_code(exit_failure_code);
  501.       end;
  502.    
  503.    frozen die_with_code(code:INTEGER) is
  504.      -- Terminate execution with exit status code `code'.
  505.      -- Do not print any message.
  506.       require
  507.      code = exit_success_code or else
  508.      code = exit_failure_code;
  509.       do
  510.      c_inline_c("exit(a1);");
  511.       end;
  512.    
  513.    exit_success_code: INTEGER is 0;
  514.    
  515.    exit_failure_code: INTEGER is 1;
  516.    
  517. feature -- Maths constants :
  518.  
  519.    Pi: DOUBLE is 3.1415926535897932384626; 
  520.      
  521.    Evalue: DOUBLE is  2.71828182845904523536;
  522.    
  523.    Deg: DOUBLE is 57.295780; -- Deg/Radian.
  524.    
  525.    Phi: DOUBLE is 1.618034; -- Golden Ratio.
  526.    
  527. feature -- Character names :
  528.  
  529.    Ctrl_a: CHARACTER is '%/1/';
  530.    Ctrl_b: CHARACTER is '%/2/';
  531.    Ctrl_c: CHARACTER is '%/3/';
  532.    Ctrl_d: CHARACTER is '%/4/';
  533.    Ctrl_e: CHARACTER is '%/5/';
  534.    Ctrl_f: CHARACTER is '%/6/';
  535.    Ctrl_g: CHARACTER is '%/7/';
  536.    Ch_del: CHARACTER is '%/8/';
  537.    Ch_tab: CHARACTER is '%/9/';
  538.    Ctrl_j: CHARACTER is '%/10/';
  539.    Ctrl_k: CHARACTER is '%/11/';
  540.    Ctrl_l: CHARACTER is '%/12/';
  541.    Ctrl_m: CHARACTER is '%/13/';
  542.    Ctrl_n: CHARACTER is '%/14/';
  543.    Ctrl_o: CHARACTER is '%/15/';
  544.    Ctrl_p: CHARACTER is '%/16/';
  545.    Ctrl_q: CHARACTER is '%/17/';
  546.    Ctrl_r: CHARACTER is '%/18/';
  547.    Ctrl_s: CHARACTER is '%/19/';
  548.    Ctrl_t: CHARACTER is '%/20/';
  549.    Ctrl_u: CHARACTER is '%/21/';
  550.    Ctrl_v: CHARACTER is '%/22/';
  551.    Ctrl_w: CHARACTER is '%/23/';
  552.    Ctrl_x: CHARACTER is '%/24/';
  553.    Ctrl_y: CHARACTER is '%/25/';
  554.    Ctrl_z: CHARACTER is '%/26/';
  555.  
  556. feature -- Hashing :
  557.    
  558.    hash_code: INTEGER is
  559.       external "CSE"
  560.       ensure
  561.      non_negative: Result >= 0
  562.       end;
  563.    
  564. feature -- Should not exist :
  565.    
  566.    not_yet_implemented is
  567.       do
  568.      std_error.put_string(
  569.       "Sorry, Some Feature is Not Yet Implemented.%N%
  570.        %Please, if you can write it by yourself and if you send me%N%
  571.        %the corresponding tested Eiffel code, I may put it in the%N% 
  572.        %standard library!%N%
  573.        %Many Thanks in advance.%N%  
  574.        %D.Colnet e-mail: colnet@loria.fr%N");
  575.      crash;
  576.        end;
  577.        
  578. feature {ANY} -- WARNING: For SmallEiffel Users's only. 
  579.    -- Using following features could makes your Eiffel code not 
  580.    -- portable on other Eiffel compilers.
  581.    
  582.    frozen is_expanded_type: BOOLEAN is
  583.      -- Target is not evaluated (Statically computed).
  584.      -- Result is true if target static type is an expanded type.
  585.      -- Usefull for formal generic type.
  586.       external "CSE"
  587.       end;
  588.    
  589.    frozen is_basic_expanded_type: BOOLEAN is
  590.      -- Target is not evaluated (Statically computed).
  591.      -- Result is true if target static type is one of the 
  592.      -- following types : BOOLEAN, CHARACTER, INTEGER, REAL,
  593.      -- DOUBLE or POINTER.
  594.       external "CSE"
  595.       ensure
  596.      Result implies is_expanded_type
  597.       end;
  598.    
  599.    object_size: INTEGER is
  600.      -- Gives the size of the current object at first level 
  601.      -- only (pointed sub-object are not concerned).  
  602.      -- The result is given in number of CHARACTER.
  603.       do
  604.      if is_expanded_type then
  605.         c_inline_c("R=sizeof(C);")
  606.      else
  607.         c_inline_c("R=s[C->id];")
  608.      end;
  609.       end;
  610.  
  611. feature {NONE} -- WARNING: For SmallEiffel Gurus's only. 
  612.    -- Using following features makes your Eiffel code not 
  613.    -- portable on other Eiffel compilers.
  614.    
  615.    c_inline_h(c_code: STRING) is
  616.      -- Target must be Current and `c_code' must be a manifest
  617.      -- string. Write `c_code' in the heading C file.
  618.       external "CSE"
  619.       end;
  620.  
  621.    c_inline_c(c_code: STRING) is
  622.      -- Target must be Current and `c_code' must be a manifest
  623.      -- string. Write `c_code' in the stream at current position.
  624.       external "CSE"
  625.       end;
  626.  
  627. feature -- WARNING: For SmallEiffel Gurus's only. 
  628.    -- Internal implementation of the SmallEiffel 
  629.    -- debugger/interpretor (command `eval').
  630.  
  631.    eval_read_attribute(name: STRING; dest: POINTER) is do end;
  632.  
  633.    eval_write_attribute(name: STRING; source: POINTER) is do end;
  634.  
  635.    frozen eval_virtual_machine: EVAL_VIRTUAL_MACHINE is
  636.       once
  637.      !!Result.make;
  638.       end;
  639.  
  640. end -- GENERAL
  641.